package cn.getech.data.development.service.impl;

import cn.getech.data.development.config.properties.BdpJobConfig;
import cn.getech.data.development.constant.RunStatus;
import cn.getech.data.development.constant.YesOrNoEnum;
import cn.getech.data.development.controller.real.RealSearchReq;
import cn.getech.data.development.controller.real.RealTimeTaskHistory;
import cn.getech.data.development.mapper.RealTimeTaskMenuMapper;
import cn.getech.data.development.mapper.flink.BdpRealTimeRunHistoryMapper;
import cn.getech.data.development.model.vo.RealTimeTaskMenuSearchVO;
import cn.getech.data.development.model.vo.RealTimeTaskOpsVO;
import cn.getech.data.development.service.RealTimeTaskMenuService;
import cn.getech.data.development.service.RealTimeTaskOpsService;
import cn.getech.data.intelligence.common.utils.DateUtils;
import cn.getech.data.intelligence.common.utils.PageUtils;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.system.center.model.dto.SysUserDto;
import cn.getech.system.center.service.SysUserRoleService;
import cn.getech.system.center.service.SysUserService;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.json.XML;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RealTimeTaskOpsServiceImpl implements RealTimeTaskOpsService {

    @Autowired
    private RealTimeTaskMenuService realTimeTaskMenuService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private BdpJobConfig bdpJobConfig;
    @Resource
    private RealTimeTaskMenuMapper realTimeTaskMenuMapper;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private BdpRealTimeRunHistoryMapper bdpRealTimeRunHistoryMapper;
    //http://bigdata-test-3:8088/ws/v1/cluster/apps/application_1600679071671_46632
    public Integer getStatus(String appId) {
        //<?xml version="1.0" encoding="UTF-8" standalone="yes"?><appstate><state>FINISHED</state></appstate>
        String[] nameNodes = bdpJobConfig.getYarnmasters().split(",");
        for (String nameNode : nameNodes) {
            String url = "http://" + nameNode + "/ws/v1/cluster/apps/" + appId;
            try {
                String data = HttpUtil.get(url, 5000);
                JSONObject json = JSONObject.parseObject(data);
                if (!json.isEmpty() && json.get("app") != null) {
                    String status = json.getJSONObject("app").getString("state");
                    if (RunStatus.FINISHED.getDesc().equals(status)) {
                        String finalStatus = json.getJSONObject("app").getString("finalStatus");
                        return RunStatus.getStatus(finalStatus);
                    } else {
                        return RunStatus.getStatus(status);
                    }
                }else{
                    org.json.JSONObject jsonXml = XML.toJSONObject(data);
                    if (null != jsonXml) {
                        String status = jsonXml.getJSONObject("app").getString("state");
                        if (RunStatus.FINISHED.getDesc().equals(status)) {
                            String finalStatus = jsonXml.getJSONObject("app").getString("finalStatus");
                            return RunStatus.getStatus(finalStatus);
                        } else {
                            return RunStatus.getStatus(status);
                        }
                    } else {
                        log.info("url:{}  \n status:\n{}", url, data);
                    }
                }
            } catch (Exception e) {
                log.warn("获取状态{}：",e.getMessage());
            }
        }
        log.warn("任务appId:{}获取状态 \n yarn master: {},配置可能出错", appId, nameNodes);
        return RunStatus.FAIL.getStatus();
    }

    @Override
    public PageUtils<RealTimeTaskHistory> findRunHistoryList(RealSearchReq params) {
        if (params.getPage() == null || params.getLimit() == null) {
            params.setPage(1);
            params.setLimit(10);
        }
        IPage<RealTimeTaskHistory> dataPage = new Page<>(params.getPage(), params.getLimit());
        params.setTenantId(ShiroUtils.getTenantId());
        IPage<RealTimeTaskHistory> page = bdpRealTimeRunHistoryMapper.selectListPage(dataPage, params);
        for (RealTimeTaskHistory record : page.getRecords()) {
            if (record.getRunTime() != null) {
                long start = record.getRunTime().getTime();
                long end = record.getEndTime() != null ? record.getEndTime().getTime() : new Date().getTime();
                long duration = (end - start) / 1000;
                String s = DateUtils.secToTime(duration);
                record.setDuration(s);
            } else if (record.getEndTime() == null) {
                record.setDuration("--");
            }
        }
        return new PageUtils<>(page);
    }

    @Override
    public JSONObject findConditionList() {
        JSONObject data=new JSONObject();
        Set<String> projects = Sets.newHashSet();
        Set<String> queueNames = Sets.newHashSet();
        Set<String> runStates = Sets.newHashSet();
        List<RealTimeTaskHistory> list = bdpRealTimeRunHistoryMapper.findProjectList(ShiroUtils.getTenantId());
        for (RealTimeTaskHistory realTimeTaskHistory : list) {
            projects.add(realTimeTaskHistory.getProcId() + ";" + realTimeTaskHistory.getProcName());
            queueNames.add(realTimeTaskHistory.getQueueName());
            runStates.add(realTimeTaskHistory.getRunState() + ";" + RunStatus.getStatusDesc(realTimeTaskHistory.getRunState()));
        }
        List<JSONObject> projectList= Lists.newArrayList();
        for (String project : projects) {
            JSONObject p=new JSONObject();
            p.put("id",project.split(";")[0]);
            p.put("name",project.split(";")[1]);
            projectList.add(p);
        }
        List<JSONObject> queueNameList= Lists.newArrayList();
        for (String queueName : queueNames) {
            JSONObject p=new JSONObject();
            p.put("name",queueName);
            p.put("id",queueName);
            queueNameList.add(p);
        }
        List<JSONObject> runStateList= Lists.newArrayList();
        for (String runState : runStates) {
            JSONObject p=new JSONObject();
            p.put("name",runState.split(";")[1]);
            p.put("id",runState.split(";")[0]);
            runStateList.add(p);
        }
        data.put("projectList",projectList);
        data.put("queueNameList",queueNameList);
        data.put("runStateList",runStateList);


        return data;
    }

    @Override
    public R opsPage(RealTimeTaskMenuSearchVO vo, Long userId) {
        if (StringUtils.isEmpty(vo.getPage()) || vo.getPage().equals("0")) {
            vo.setPage("1");
        }
        if (StringUtils.isEmpty(vo.getLimit())) {
            vo.setLimit("10");
        }
        Integer tenantId = ShiroUtils.getTenantId();
        if(sysUserRoleService.superAdmin(userId)){
            vo.setUserId(null);
        }else{
            vo.setUserId(userId);
        }
        vo.setTenantId(tenantId);
        try {
            IPage<RealTimeTaskOpsVO> page = realTimeTaskMenuService.pageList(new Page(Long.valueOf(vo.getPage()), Long.valueOf(vo.getLimit())), vo);
            List<SysUserDto> userList = sysUserService.listAllUsers();
            Map<Long, String> userMap = userList.stream().collect(
                    Collectors.toMap(SysUserDto::getUserId, SysUserDto::getUsername));

            List<Integer> procIds = realTimeTaskMenuMapper.getProcIdByUser(userId);
            for (RealTimeTaskOpsVO record : page.getRecords()) {
                if (procIds != null && procIds.contains(record.getProcId())) {
                    record.setEnableOp(YesOrNoEnum.YES.getValue());
                }else{
                    record.setEnableOp(YesOrNoEnum.NO.getValue());
                }
                if (record.getCreatePer() != null) {
                    record.setCreatePerName(userMap.get(record.getCreatePer()));
                }
                if (record.getUpdatePer() != null) {
                    record.setUpdatePerName(userMap.get(record.getUpdatePer()));
                }
                if (RunStatus.WAIT.getStatus().equals(record.getRunState())) {
                    record.setUpdatePerName("--");
                    record.setUpdateTime(null);
                }
                if (RunStatus.RUNNING.getStatus().equals(record.getRunState())) {
                    Long now = new Date().getTime();
                    if (record.getRunTime() != null) {
                        long time = record.getRunTime().getTime();
                        long duration = (now - time) / 1000;
                        String s = DateUtils.secToTime(duration);
                        record.setDuration(s);
                    } else {
                        record.setDuration("--");
                    }
                } else {
                    record.setDuration("--");
                }
            }
            Map<String, Object> countMap = realTimeTaskMenuMapper.jobReportCount(vo);
            JSONObject data=new JSONObject();
            data.put("countMap",countMap);
            data.put("page",new PageUtils(page));
            return R.okWithPage(data);
        } catch (Exception e){
            log.error("获取实时任务运维分页列表出错：", e);
        }
        return R.ok();
    }

}
